package com.source.auto.utils;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.source.auto.model.JsonConfigInfo;
import com.source.auto.model.ServiceInfo;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class FileUtil {

    private static final int THREAD_POOL_SIZE = 10; // 设置线程池大小，根据实际需要调整


    /**
     * 递归查找目录下所有的 .git 文件夹路径(单线程版本)
     *
     * @param directory 目录
     * @return {@link List }<{@link String }>
     * @throws IOException io异常
     */
    public static List<String> findGitRepositories(File directory) throws IOException {

        List<String> gitRepos = new ArrayList<>();
        if (directory.exists() && directory.isDirectory()) {
            AtomicInteger count = new AtomicInteger();
            Files.walk(directory.toPath())
                .filter(path -> path.toString().endsWith(".git"))
                .forEach(path -> {
                    gitRepos.add(path.getParent().toString());
                    count.getAndIncrement();
                    LogUtil.infoPrint("累计扫描 {} 次,找到 .git repository at:{} \r",count.get(), path.getParent());
                }); // 找到.git文件夹
        }
        return gitRepos;
    }


    /**
     * 加载 JSON 配置
     *
     * @return {@link JsonConfigInfo }
     */
    public static JsonConfigInfo loadJsonConfig(String jsonPath) {

        // 使用相对路径获取 Path 对象
        Path path = Paths.get(jsonPath);

        // 读取文件内容
        try {
            StringBuilder stringBuilder = new StringBuilder();
            Files.lines(path).forEach(stringBuilder::append);
            if (StrUtil.isNotBlank(stringBuilder.toString())) {
                // 转换为 Java 对象
                return JSONUtil.toBean(stringBuilder.toString(), JsonConfigInfo.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, String> loadContentByPath(String relativePath) {
        // 使用相对路径获取 Path 对象
        Path path = Paths.get(relativePath);
        Map<String, String> map = new HashMap<>();
        // 读取文件内容
        try {
            Files.lines(path).forEach(f -> {
                String[] split = f.split("@");
                if (ArrayUtil.isEmpty(split)) {
                    return;
                }
                map.put(split[0], split[1]);
            });
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 查找项目中所有的 pom.xml 文件
     */
    public static List<File> findPomXmlFiles(String folderPath) {
        List<File> pomFiles = new ArrayList<>();
        try {
            Files.walk(Paths.get(folderPath))
                .filter(path -> path.toFile().getName().equals("pom.xml"))
                .forEach(path -> pomFiles.add(path.toFile()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pomFiles;
    }

    public static ServiceInfo analyzePomFile(File pomFile) {
        try {
            ServiceInfo serviceInfo = new ServiceInfo();

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(pomFile);

            Element root = document.getDocumentElement();

            // 判断是否有 <modules> 标签
            NodeList modulesList = root.getElementsByTagName("modules");
            if (modulesList.getLength() > 0) {
                LogUtil.printf(
                    "解析 " + pomFile.getPath() + ": 检测到当前pom是父工程，包含以下模块：");
                NodeList moduleNodes = modulesList.item(0).getChildNodes();
                for (int i = 0; i < moduleNodes.getLength(); i++) {
                    Node moduleNode = moduleNodes.item(i);
                    if (moduleNode.getNodeType() == Node.ELEMENT_NODE) {
                        LogUtil.printf("    - 模块: " + moduleNode.getTextContent().trim());
                    }
                }
                return null; // 父工程处理完毕，直接返回
            }

            // 获取 <project> 标签下的 <artifactId>
            String artifactId = getProjectArtifactId(root);
            if (artifactId != null) {
                LogUtil.printf("解析 {}: {}", pomFile.getPath(), artifactId);

                // 检查 dependency 中是否包含 bee-core 或 spring-boot-*
                boolean isExecutable = checkExecutableDependencies(root);

                // 根据 artifactId 自动分类
                String type = classifyArtifactId(artifactId, isExecutable);
                if (type == null) {
                    // 忽略当前项目
                    return null;
                }

                serviceInfo.setServiceName(artifactId);
                serviceInfo.setServiceType(type);
                return serviceInfo;
            } else {
                LogUtil.printf("未找到 <artifactId> 标签，跳过该文件。");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取 <project> 标签下的 <artifactId>
     */
    public static String getProjectArtifactId(Element root) {
        if (!"project".equals(root.getTagName())) {
            LogUtil.printf("当前文件根标签不是 <project>，请检查文件格式。");
            return null;
        }

        NodeList childNodes = root.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node childNode = childNodes.item(i);
            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element) childNode;
                if ("artifactId".equals(childElement.getTagName())) {
                    return childElement.getTextContent().trim();
                }
            }
        }
        return null; // 如果未找到 <artifactId>
    }


    /**
     * 检查是否包含可执行的依赖（bee-core 或 spring-boot-*）
     */
    public static boolean checkExecutableDependencies(Element root) {
        NodeList dependenciesList = root.getElementsByTagName("dependency");
        for (int i = 0; i < dependenciesList.getLength(); i++) {
            Node dependencyNode = dependenciesList.item(i);
            if (dependencyNode.getNodeType() == Node.ELEMENT_NODE) {
                Element dependencyElement = (Element) dependencyNode;
                String artifactId = getChildTagValue(dependencyElement, "artifactId");

                // TODO：可自定义
                if ("bee-core".equals(artifactId) || (artifactId != null && artifactId.startsWith(
                    "spring-boot"))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取子标签的值
     */
    public static String getChildTagValue(Element element, String tagName) {
        NodeList nodeList = element.getElementsByTagName(tagName);
        if (nodeList.getLength() > 0) {
            return nodeList.item(0).getTextContent().trim();
        }
        return null;
    }

    /**
     * 根据 artifactId 自动分类
     */
    public static String classifyArtifactId(String artifactId, boolean isExecutable) {
        if (isExecutable) {
            if (artifactId.contains("-web")) {
                return "web";
            } else if (artifactId.contains("-service")) {
                return "service";
            } else {
                LogUtil.error(
                    "检测到 {} 为可执行程序，但未能自动分类，请手动配置类型(service/web or ignore)",
                    artifactId);
                while (true) {
                    Scanner scanner = new Scanner(System.in);
                    String next = scanner.next();
                    if ("ignore".equals(next)) {
                        return null;
                    }
                    if ("web".equals(next) || "service".equals(next)) {
                        return next;
                    }
                    LogUtil.error("请输入正确的类型(web/service or ignore): ");
                }
            }
        } else if (artifactId.contains("-api")) {
            return "api";
        } else {
            LogUtil.error("无法分类 artifactId: {}，请手动配置类型(api/service/web or ignore)。",
                artifactId);
            while (true) {
                Scanner scanner = new Scanner(System.in);
                String next = scanner.next();
                if ("ignore".equals(next)) {
                    return null;
                }
                if ("api".equals(next) || "web".equals(next) || "service".equals(next)) {
                    return next;
                }
                LogUtil.error("请输入正确的类型(api/web/service or ignore): ");
            }
        }
    }

    /**
     * 覆盖文件内容的方法
     *
     * @param filePath 文件路径
     * @param content  新内容
     */
    public static void overwriteFile(String filePath, String content) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write(content); // 写入新内容，原内容会被覆盖
            LogUtil.printf("文件内容已成功刷新！");
        } catch (IOException e) {
            LogUtil.printf("写入文件时出错：{}", e.getMessage());
        }
    }
}
